import VueRouter from 'vue-router'

VueRouter.prototype.ln = (path, to)->
    pos = path.indexOf(' ')
    history = @history

    route = @match('/'+path, history.current)
    history.confirmTransition(
        route
        =>
            history.updateRoute(route)
            setTimeout =>
                if not to
                    to = location.pathname+location.search
                history.current = @match(
                    to
                    history.current
                )
                _loaded(0)
                history.ensureURL()
    )
    return

VueRouter.prototype.reload = ->
    history = @history
    current = history.current
    GO.go current
    return

module.exports = VueRouter

# `const AsyncFunction = (async ()=>{}).constructor`

# async_data = (mod)->
#     data = mod.data
#     _ = undefined


#     beforeRouteEnter = mod.beforeRouteEnter

#     if beforeRouteEnter
#         mod.beforeRouteEnter = (from, to, next)->
#             _ = await data()
#             beforeRouteEnter.apply(@,arguments)
#     else
#         mod.beforeRouteEnter = (from, to, next)->
#             _ = await data()
#             next()

#     mod.data = ->
#         _



MOD = require '../../.import'
CLS_LOADING = 'I-loading'
_LOADING = 0
_loaded = (n)->
    if n!=undefined
        _LOADING = n
    if (not _LOADING) or (not (-- _LOADING))
        $('body').removeClass CLS_LOADING

_component = (k, patch)->
    =>
        if ++ _LOADING < 2
            $('body').addClass CLS_LOADING
        mod = (await MOD[k]).default
        # data = mod.data
        # if data instanceof AsyncFunction
        #     async_data(mod)
        mod = _loading_patch(mod)
        if patch
            patch(mod)
        return mod

import {Store} from 'vuex'

beforeRouteEnter = require("../_vue/beforeRouteEnter")
_beforeRouteUpdate = (func)->
    (to, from, next)->
        _next = (func)=>
            if $.isFunction(func)
                func.apply @
                next()
            else
                next.apply @,arguments
        func.call @, to, from, _next


_loading_patch = (mod)->
    body = $ 'body'
    beforeRouteUpdate = mod.beforeRouteUpdate

    if beforeRouteUpdate
        beforeRouteEnter(
            mod
            beforeRouteUpdate
        )
        mod.beforeRouteUpdate = _beforeRouteUpdate(beforeRouteUpdate)

    if mod.store and not mod.store._vm
        mod.store = new Store(mod.store)

    beforeRouteEnter(
        mod
        (to, from, next)->
            try
                await next()
            finally
                _loaded()
    )


    return mod

#添加嵌套路由
_child = (child,_prefix) ->
    li = []
    for k,v of child
        is_str = typeof(v) == "string"
        if is_str
            file = v
        else
            file = k
        prefix = _prefix+"/"+file
        o = {
            path : k
            component: _component(prefix)
        }
        if not is_str
            o.children = _child(v,prefix)
        li.push o
    return li

_load = (dict, _routes, prefix="")->
    for path,mod of dict.default
        if Array.isArray(mod)
            [mod,child] = mod
        if typeof(mod) == "string"
            _path = "/"+prefix+path
            mod_path = (prefix or require('~config/site')+"/") + mod
            o = {
                path:_path
                component : _component(
                    mod_path
                    dict.patch
                )
            }
            if child
                li = _child(child,mod_path)
                o.children = li
            _routes.push o
        else
            _prefix = prefix+path
            if _prefix.length
                _prefix += "/"

            _load(mod, _routes, _prefix)


window.GO = new VueRouter({
    mode: 'history'
    routes: do ->
        _routes = []
        _load(require('../../.route'), _routes)
        _routes.push {
            path:"*"
            component: ->
                mod = await `import("../../vue/404.vue")`
                return _loading_patch(mod.default)
        }
        _routes
})
